import os
import subprocess
import tkinter as tk
from tkinter.filedialog import askopenfile
from tkinter.filedialog import askdirectory
from tkinter import Entry
import RUNME

openCSD_path = ""
snap_bin_path = ""
compiler_path = ""
ELF_path = ""
trace_ID = ""


# instructions
def open_CSD_dir():
    global openCSD_path
    dir = askdirectory(parent=root, title="Choose a directory")
    if dir:
        openCSD_path = dir
        text_box.config(state="normal")
        text_box.insert("end", "\nOpenCSD loaded: " + openCSD_path)
        text_box.see("end")
        text_box.config(state="disabled")
        my_canvas.itemconfig(openCSD_led, fill="green")


def open_snap_bin_dir():
    global snap_bin_path
    dir = askdirectory(parent=root, title="Choose a directory")
    if dir:
        snap_bin_path = dir
        text_box.config(state="normal")
        text_box.insert("end", "\nSnapshots and binaries loaded: " + snap_bin_path)
        text_box.see("end")
        text_box.config(state="disabled")
        my_canvas.itemconfig(snap_bin_led, fill="green")


def open_compiler_dir():
    global compiler_path
    dir = askdirectory(parent=root, title="Choose a directory")
    if dir:
        compiler_path = dir
        text_box.config(state="normal")
        text_box.insert("end", "\nArm Compiler loaded: " + compiler_path)
        text_box.see("end")
        text_box.config(state="disabled")
        my_canvas.itemconfig(compiler_led, fill="green")


def open_file():
    global ELF_path
    file = askopenfile(parent=root, title="Choose a file")
    if file:
        ELF_path = file.name
        text_box.config(state="normal")
        text_box.insert("end", "\nELF file loaded: " + ELF_path)
        text_box.see("end")
        text_box.config(state="disabled")
        my_canvas.itemconfig(elf_led, fill="green")


def load_ID():
    global trace_ID
    trace_ID = trace_ID_entry.get()
    text_box.config(state="normal")
    text_box.insert("end", "\nTrace ID loaded: " + trace_ID)
    text_box.see("end")
    text_box.config(state="disabled")
    my_canvas.itemconfig(traceID_led, fill="green")


def run_program():
    if not openCSD_path:
        text_box.config(state="normal")
        text_box.insert("end", f"\nOpenCSD folder is not specfied")
        text_box.see("end")
        return
    if not trace_ID:
        text_box.config(state="normal")
        text_box.insert("end", f"\nTrace ID is not specfied")
        text_box.see("end")
        return
    if not snap_bin_path:
        text_box.config(state="normal")
        text_box.insert("end", f"\nSnapshot folder is not specfied")
        text_box.see("end")
        return
    if not compiler_path:
        text_box.config(state="normal")
        text_box.insert("end", f"\nArm Compiler folder is not specfied")
        text_box.see("end")
        return
    if not ELF_path:
        text_path.config(state="normal")
        text_box.insert("end", f"\nElf file path is not specified")
        text_box.see("end")
        return

    text_box.config(state="normal")
    text_box.insert("end", f"\nRunning Trace Decode...")
    text_box.see("end")
    text_box.config(state="disabled")

    output_file = "trace_full.txt"
    text_box.config(state="normal")
    if not RUNME.run(
        openCSD_path, trace_ID, snap_bin_path, compiler_path, ELF_path, output_file
    ):
        text_box.insert(
            "end",
            f"\nThe trace decoder was running failed. Please check logfile for detail.",
        )
        text_box.see("end")
        return
    text_box.insert(
        "end",
        f"\nThe trace decoder was running successfully. Please check file {os.path.abspath(output_file)} for output.",
    )
    return


if __name__ == "__main__":

    root = tk.Tk()

    # button 1 - OpenCSD select
    browse_openCSD = tk.StringVar()
    browse_openCSD_btn = tk.Button(
        root,
        textvariable=browse_openCSD,
        command=lambda: open_CSD_dir(),
        height=5,
        width=20,
    )
    browse_openCSD.set("Select OpenCSD folder")
    browse_openCSD_btn.grid(column=0, row=0, rowspan=3, pady=10, padx=5)

    # button 2 - Snapshot directory select
    browse_snap_bin = tk.StringVar()
    browse_snap_bin_btn = tk.Button(
        root,
        textvariable=browse_snap_bin,
        command=lambda: open_snap_bin_dir(),
        height=5,
        width=20,
    )
    browse_snap_bin.set("Select snapshot/bin folder")
    browse_snap_bin_btn.grid(column=2, row=0, rowspan=3, pady=10, padx=5)

    # button 3 - Arm compiler select
    browse_compiler = tk.StringVar()
    browse_compiler_btn = tk.Button(
        root,
        textvariable=browse_compiler,
        command=lambda: open_compiler_dir(),
        height=5,
        width=20,
    )
    browse_compiler.set("Select Arm Compiler folder")
    browse_compiler_btn.grid(column=0, row=3, pady=10, padx=5)

    # button 4 - ELF file select
    browse_elf = tk.StringVar()
    browse_elf_btn = tk.Button(
        root, textvariable=browse_elf, command=lambda: open_file(), height=5, width=20
    )
    browse_elf.set("Select ELF file")
    browse_elf_btn.grid(column=2, row=3, pady=10, padx=5)

    # button 5 - Run
    run_decode_btn = tk.Button(
        root, text="Run", command=lambda: run_program(), height=5, width=20
    )
    run_decode_btn.grid(column=1, row=4, pady=10, padx=5)

    # entry to set Trace ID
    trace_ID_label = tk.Label(root, text="Enter Trace ID")
    trace_ID_label.grid(column=1, row=0, sticky="S")

    trace_ID_entry = Entry(root, width=10)
    trace_ID_entry.grid(column=1, row=1)

    trace_ID_btn = tk.Button(root, text="Enter", command=lambda: load_ID())
    trace_ID_btn.grid(column=1, row=2, sticky="N")

    # textbox for output
    text_box = tk.Text(root, height=10, width=80)
    text_box.config(state="disabled")
    text_box.grid(column=0, row=5, columnspan=3, padx=5, pady=10)

    # Indicators for loading
    my_canvas = tk.Canvas(root, width=150, height=50)  # , bg="white")
    my_canvas.grid(column=1, row=3, sticky="S")

    snap_bin_led = my_canvas.create_oval(70, 32, 80, 42, fill="red")
    snap_bin_lbl = tk.Label(my_canvas, text="b", font=("Times 15"))
    snap_bin_lbl.place(x=69, y=4)

    openCSD_led = my_canvas.create_oval(20, 32, 30, 42, fill="red")
    openCSD_lbl = tk.Label(my_canvas, text="s", font=("Times 15"))
    openCSD_lbl.place(x=20, y=4)

    traceID_led = my_canvas.create_oval(45, 32, 55, 42, fill="red")
    traceID_lbl = tk.Label(my_canvas, text="id", font=("Times 15"))
    traceID_lbl.place(x=41, y=4)

    compiler_led = my_canvas.create_oval(95, 32, 105, 42, fill="red")
    compiler_lbl = tk.Label(my_canvas, text="c", font=("Times 15"))
    compiler_lbl.place(x=94, y=4)

    elf_led = my_canvas.create_oval(120, 32, 130, 42, fill="red")
    elf_lbl = tk.Label(my_canvas, text="e", font=("Times 15"))
    elf_lbl.place(x=120, y=4)

    root.mainloop()
